import { IncomingMessage, ServerResponse } from 'http'
import { ObjectId } from "mongodb";
import * as ws from 'ws'

export interface LoginUser {
    name: string;
    username: string;
    token: string;
}
export interface SimpleUser extends Omit<LoginUser, 'token'> {
    group?: string;
    avatar?: string;
}
export type FetchResult<F> = {
    success?: true;
    data?: F;
    error?: string;
    location?: string;
}

/** 服务端使用配置 */
export interface ApiContext {
    loginUser: LoginUser;
    req?: IncomingMessage;
}
export interface FetchAPI<T = any, F = any> {
    (
        body?: T,
        /** 服务端接口需要使用 */
        context?: ApiContext
    ): Promise<FetchResult<F>>
}

/** 服务端缓存连接 */
export interface ClientInfo {
    /** 客户端标记 */
    uuid: string;
    username: string;
    gmt_create: number;
    gmt_update: number;
    req: IncomingMessage;
    resp?: ServerResponse;
    ws?: ws.WebSocket;
}

export interface BaseInfo {
    _id?: string | ObjectId;
    created_by: string;
    modified_by: string;
    gmt_created: number;
    gmt_modified: number;
}

export interface UploadInfo {
    filename: string;
    md5: string;
    size: number;
}
export interface ChatRoomUser {
    username: string;
    /** 群管理员 */
    is_admin?: boolean;
    /** 群主，创建者 */
    is_master?: boolean;
    /** 群内被禁言 */
    is_muted?: boolean;
    /** 普通成员不可见用户，可以用来旁观 */
    is_hidden?: boolean;
}
export interface ChatRoom {
    name: string;
    desc?: string;
    users: ChatRoomUser[];
    delete_users?: LoginUser['username'][];
    /** 公告 */
    notice?: string;
    /** 全员禁言，管理员除外 */
    is_muted?: boolean;
    /** 群已解散 */
    is_deleted?: boolean;
    /** 解散原因描述 */
    delete_reason?: string;
    /** 受控状态： 不可通过WEB操作修改群信息和删除修改群成员 */
    is_controlled?: boolean;
}
export enum ChatMessageType {
    TXT = 'txt',
    IMG = 'img',
    VIDEO = 'video',
    FILE = 'file',
    LINK = 'link',
    /** 需要解析title的链接 */
    LINK_WITH_TITLE = 'link_with_title',
}

export interface FetchRenderProps {
  /** 获取信息URL */
  url: string;
  /** 根据获取信息拼接展示title */
  template: string;
}
/** 渲染规则结果 */
export type RenderItem <T extends ChatMessageType = ChatMessageType> = T extends infer K extends ChatMessageType ? {
    type: K;
    body: string;
    render?: K extends ChatMessageType.LINK_WITH_TITLE ? FetchRenderProps : never
} : never;
export interface ChatMessage {
    type: ChatMessageType;
    body: string;
    /** 根据规则判断渲染结果 */
    render_items?: RenderItem[];
    chatroom_id: BaseInfo['_id'];
    canceled?: boolean;
}

export interface ServerErrorInfo {
    error: string;
    ts: number;
}
export interface LogAll {
    /** 链接成功 */
    connect: Omit<ClientInfo, 'req' | 'resp'>[];
    server_error: ServerErrorInfo;

    message_send: ChatMessage & BaseInfo;
    message_cancel: ChatMessage & BaseInfo;
    chatroom_create: ChatRoom & BaseInfo;
    chatroom_update: ChatRoom & BaseInfo;
    chatroom_adduser: {
      chatroom_id: BaseInfo['_id'];
      users: string[];
    };
    chatroom_deluser:  {
      chatroom_id: BaseInfo['_id'];
      users: string[];
    };
    /** 成员属性修改 */
    chatroom_user_change: {
      chatroom_id: BaseInfo['_id'];
      /** 设置/取消管理员， 设置/取消隐藏， 设置/取消禁言， 转让群主 */
      action: 'to_admin' | 'off_admin' | 'to_hidden' | 'off_hidden' | 'to_mute' | 'off_mute' | 'to_master';
      user: string;
    };
    /** 聊天室全体禁言 */
    chatroom_mute: {
        chatroom_id: BaseInfo['_id'];
        action: 'to_mute' | 'off_mute';
    };
    chatroom_delete: ChatRoom & BaseInfo;
}

export type LogRuntime = keyof Pick<LogAll, 'connect' | 'server_error'>
export type LogMessage<T extends keyof LogAll = keyof LogAll> = T extends infer K extends keyof LogAll ? {
  type: K,
  message: LogAll[K]
  chatroom_id: K extends LogRuntime ? undefined : BaseInfo['_id'];
  to: string[];
} : never;
